import { AmbientLight, AxesHelper, BoxBufferGeometry, Camera, GridHelper, Mesh, MeshStandardMaterial, PerspectiveCamera, Scene, Vector3, WebGLRenderer, MOUSE, Object3D } from 'three'

import Stats from 'three/examples/jsm/libs/stats.module'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'

export class TEngine {

    private dom: HTMLElement
    private renderer: WebGLRenderer

    //创建场景？
    private scene: Scene
    //创建相机 透视相机
    private camera: PerspectiveCamera

    constructor(dom: HTMLElement) {
        this.dom = dom
        this.renderer = new WebGLRenderer({
            antialias: true
        }) //设置抗锯齿
        //上面创建变量，在这里声明创建
        this.scene = new Scene()
        this.camera = new PerspectiveCamera(45, dom.offsetWidth / dom.offsetHeight, 1, 1000)
        //设置相机位置
        this.camera.position.set(40, 40, 40)
        //设置相机指向的坐标
        this.camera.lookAt(new Vector3(0, 0, 0))
        //相机镜头朝向位置
        this.camera.up = new Vector3(0, 1, 0)



        console.log('three')

        // this.renderer.domElement.width = dom.offsetWidth
        // this.renderer.domElement.height = dom.offsetHeight
        //上述两段代码的简写
        this.renderer.setSize(dom.offsetWidth, dom.offsetHeight, true)


        //创建环境光
        const ambientLight: AmbientLight = new AmbientLight('rgb(255,255,255)', 1)

        //添加一个辅助的线条  参数控制辅助线条的大小
        const axesHelper: AxesHelper = new AxesHelper(300)
        //添加地板网格  范围  均分多少份  主轴颜色  网格边框颜色
        const gridHelper: GridHelper = new GridHelper(500, 20, 'rgb(255,100,100)', 'rgb(100,100,100)')

        //物体对象被统一放置到另外一个ts中统一管理
        //this.scene.add(box)
        this.scene.add(ambientLight)
        this.scene.add(axesHelper)
        this.scene.add(gridHelper)
        //画布颜色
        //this.renderer.setClearColor('rgb(255,255,255)')
        //注释掉无任何影响
        // this.renderer.clearColor()

        //性能监视器  ts中检查很严格，非class类不可以new 非核心库，需要自己引用
        const stats = Stats()
        //设置监视器可以被调用的变量
        const statsDom = stats.domElement
        //设置statsDom在前端显示的位置
        statsDom.style.position = 'fixed'
        statsDom.style.top = '0'
        statsDom.style.right = '0'
        statsDom.style.zIndex = '1'
        statsDom.style.left = 'unset'

        //初始鼠标控制场景  非核心库，需要自己引用
        const orbitControls: OrbitControls = new OrbitControls(this.camera, this.renderer.domElement)
        orbitControls.enableDamping = true //旋转时候增加阻尼感
        //设置鼠标控制事件
        orbitControls.mouseButtons = {
            LEFT: null as unknown as MOUSE, //鼠标左键设置为空
            MIDDLE: MOUSE.DOLLY,
            RIGHT: MOUSE.ROTATE
        }



        const renderFun = () => {
            //box.position.y += 0.01  //模型移动
            //画布中渲染场景和相机
            orbitControls.update()
            stats.update()
            this.renderer.render(this.scene, this.camera)
            requestAnimationFrame(renderFun)
        }

        //运行变量，不然画布无法渲染
        renderFun()
        dom.appendChild(this.renderer.domElement)
        //在前端进行渲染
        dom.appendChild(statsDom)
    }

    addObject(...object: Object3D[]) {
        object.forEach(elem => {
            this.scene.add(elem)
        })
    }

}